package org.elasticsearch;

import org.elasticsearch.cluster.metadata.RepositoryMetaData;
import org.elasticsearch.common.blobstore.BlobContainer;
import org.elasticsearch.common.blobstore.BlobMetaData;
import org.elasticsearch.common.blobstore.BlobPath;
import org.elasticsearch.common.lucene.store.ByteArrayIndexInput;
import org.elasticsearch.common.lucene.store.InputStreamIndexInput;
import org.elasticsearch.common.settings.Settings;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;


public class ObsBlobContainerTest {

    private RepositoryMetaData metadata;
    private ObsBlobContainer obsBlobContainer;

    @org.junit.jupiter.api.BeforeEach
    public void initObsBlobContainer() {
        Settings settings2 = Settings.builder()
                .put(ObsClientSettings.BUCKET.getKey(), "bucket")
                .put(ObsClientSettings.ACCESS_KEY.getKey(), "access_key")
                .put(ObsClientSettings.SECRET_ACCESS_KEY.getKey(), "secret_key")
                .put(ObsClientSettings.SECURITY_TOKEN.getKey(), "security_token")
                .put(ObsClientSettings.ENDPOINT.getKey(), "endpoint")
                .build();
        metadata = new RepositoryMetaData("first", ObsRepository.TYPE, settings2);

        obsBlobContainer = new ObsBlobContainer(
                new BlobPath(),
                new ObsBlobStore(new ObsService(), "bucket", false, ObsRepository.BUFFER_SIZE_SETTING.getDefault(Settings.EMPTY),
                        AclType.PublicRead.getCannedAcl(), ObsRepository.STORAGE_CLASS_SETTING.getDefault(Settings.EMPTY), metadata));
    }

    @org.junit.jupiter.api.Test
    public void blobExists() {

        boolean res = obsBlobContainer.blobExists("blob");

    }

    @org.junit.jupiter.api.Test
    public void readBlob() throws IOException {
        InputStream res = obsBlobContainer.readBlob("blob");
        BufferedReader reader = new BufferedReader(new InputStreamReader(res));
        reader.close();
    }

    @org.junit.jupiter.api.Test
    public void readBlobByPosition() throws IOException {
        InputStream res = obsBlobContainer.readBlob("blob", 0, 100);
        BufferedReader reader = new BufferedReader(new InputStreamReader(res));
        System.out.println(reader.read(new char[100]));
        reader.close();
    }

    @org.junit.jupiter.api.Test
    public void writeBlob() throws IOException {
        int size = 5 * 1024 * 1024;
        Random random = new Random();
        byte[] bytes = new byte[size];
        for (int i = 0; i < size; i++) {
            bytes[i] = (byte) random.nextInt();
        }
        try (InputStream stream = new InputStreamIndexInput(new ByteArrayIndexInput("desc", bytes), bytes.length)) {
            obsBlobContainer.writeBlob("blob", stream, bytes.length, false);
        }
    }

    @org.junit.jupiter.api.Test
    public void writeBlobAtomic() throws IOException {
        int size = 5 * 1024 * 1024;
        Random random = new Random();
        byte[] bytes = new byte[size];
        for (int i = 0; i < size; i++) {
            bytes[i] = (byte) random.nextInt();
        }
        try (InputStream stream = new InputStreamIndexInput(new ByteArrayIndexInput("desc", bytes), bytes.length)) {
            obsBlobContainer.writeBlobAtomic("blob", stream, bytes.length, false);
        }
    }

    @org.junit.jupiter.api.Test
    public void delete() throws IOException {
        obsBlobContainer.delete();
    }

    @org.junit.jupiter.api.Test
    public void listBlobsByPrefix() throws IOException {
        Map<String, BlobMetaData> res = obsBlobContainer.listBlobsByPrefix("bl");
    }

    @org.junit.jupiter.api.Test
    public void listBlob() throws IOException {
        Map<String, BlobMetaData> res = obsBlobContainer.listBlobs();

    }

    @org.junit.jupiter.api.Test
    public void children() throws IOException {
        Map<String, BlobContainer> res = obsBlobContainer.children();
        System.out.println(res);
    }
}
